/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.model.command;

import static com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil.createUniqueName;
import static com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil.getOwnedBehaviors;

import org.eclipse.gef.commands.Command;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.Collaboration;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.UMLFactory;

/**
 * Command to create instances of Interactions.
 * <p>
 * The following attributes must be set for the command to complete successfully:
 * </p>
 * <ul>
 * <li>Namespace - The namespace to add the Interaction to. Any Classifier can
 * theoretically own an Interaction, but we currently only support BehavioredClassifier
 * (ie. Class, Collaboration, other Interactions for advanced modelling). In addition, a
 * Model can also be a valid namespace.
 * </ul>
 * <p>
 * The following attributes can be read to access the result of the command:
 * </p>
 * <ul>
 * <li>Interaction
 * </ul>
 * 
 * @author frankd@ifi.uio.no
 */
public class CreateInteractionCommand extends Command {

    private Namespace namespace;
    private Interaction interaction;

    // will be non-null if a collaboration is created by this command
    private Collaboration collaboration;

    public void setNamespace(final Namespace namespace) {
        this.namespace = namespace;
    }

    public Interaction getInteraction() {
        return interaction;
    }

    @Override
    public void execute() {
        interaction = UMLFactory.eINSTANCE.createInteraction();
        interaction.setName(createUniqueName(namespace, "Interaction"));

        final BehavioredClassifier parent;
        if (namespace instanceof BehavioredClassifier) {
            parent = (BehavioredClassifier) namespace;
            getOwnedBehaviors((BehavioredClassifier) namespace).add(interaction);
        } else if (namespace instanceof org.eclipse.uml2.uml.Package) {
            org.eclipse.uml2.uml.Package pkg = (org.eclipse.uml2.uml.Package) namespace;
            // 27-08-2007 : We must nit create a collaboration.
            // collaboration = UMLFactory.eINSTANCE.createCollaboration();
            // collaboration.setName(createUniqueName(namespace, "Collaboration"));
            // // getPackagedElements(pkg).add(collaboration);
            // collaboration.setPackage(pkg);
            pkg.getPackagedElements().add(interaction);
        } else
            throw new IllegalArgumentException("Unsupported Interaction namespace: " + namespace);

        /*
         * Collaboration coll; if (namespace instanceof Collaboration) coll =
         * (Collaboration) namespace; else { collaboration =
         * UMLFactory.eINSTANCE.createCollaboration(); coll = collaboration;
         * coll.setName(createUniqueName(namespace, "Collaboration"));
         * namespace.getOwnedMembers().add(coll); } interaction =
         * UMLFactory.eINSTANCE.createInteraction();
         * interaction.setName(createUniqueName(coll, "Interaction"));
         * coll.getOwnedBehaviors().add(interaction);
         */
    }

    @Override
    public void undo() {
        // 27-08-2007
        // BehavioredClassifier owner = (BehavioredClassifier) interaction.getContext();
        // getOwnedBehaviors(owner).remove(interaction);
        org.eclipse.uml2.uml.Element element = interaction.getOwner();
        if (element instanceof BehavioredClassifier) {
            getOwnedBehaviors((BehavioredClassifier) element).remove(interaction);
        } else if (element instanceof Package) {
            ((org.eclipse.uml2.uml.Package) interaction).getPackagedElements().remove(interaction);
        }

        /*
         * Collaboration coll = (Collaboration) interaction.getContext();
         * coll.getOwnedBehaviors().remove(interaction); interaction = null;
         */

        if (collaboration != null) {
            collaboration.setPackage(null);
            // getOwnedMembers(namespace).remove(collaboration);
            collaboration = null;
        }
    }

    @Override
    public void redo() {
        super.redo();
    }

    @Override
    public void dispose() {
        namespace = null;
        interaction = null;
        collaboration = null;
    }
}
